﻿using System;
using System.Diagnostics;

namespace DotNet.Common
{
    public class DoubleRange
    {
        private double _min, _max;

        public double Min
        {
            get { return _min; }
            set { _min = value; }
        }

        public double Max
        {
            get { return _max; }
            set { _max = value; }
        }

        public double Range
        {
            get
            {
                return _max - _min;
            }
        }

        public bool IsGood
        {
            get
            {
                return _min <= _max;
            }
        }

        public static DoubleRange Empty
        {
            get { return new DoubleRange(0, 0); }
        }

        public static DoubleRange GetRange(double[] dataArray)
        {
            double min, max;

            if (!CommonMath.MinMax(dataArray, out min, out max))
                return DoubleRange.Empty;

            return new DoubleRange(min, max);
        }

        public DoubleRange()
        {
            _min = 0;
            _max = 1;
        }

        public DoubleRange(double min, double max)
        {
            Debug.Assert(min <= max);

            _min = min;
            _max = max;
        }

        public bool Contain(DoubleRange otherRange)
        {
            return !(_min > otherRange.Max || _max < otherRange.Min);
        }

        public bool Contain(double data)
        {
            return data >= _min && data < _max;
        }

        public double Nearest(double data)
        {
            return CommonMath.Nearest(data, _min, _max);
        }

        public void CopyFrom(DoubleRange targetRange)
        {
            if (targetRange == null)
                return;

            _min = targetRange.Min;
            _max = targetRange.Max;
        }

        public void Shift(double shiftvalue)
        {
            _min += shiftvalue;
            _max += shiftvalue;
        }

        public void Adjust(double minimum, double maximum)
        {
            Debug.Assert(minimum <= maximum);

            if (this.Range >= maximum - minimum)
            {
                _min = minimum;
                _max = maximum;
            }
            else
            {
                if (_min < minimum)
                {
                    _max += (minimum - _min);
                    _min = minimum;
                }
                if (_max > maximum)
                {
                    _min -= (_max - maximum);
                    _max = maximum;
                }
            }
        }

        public override string ToString()
        {
            return string.Format("Min:{0} Max:{1}", _min, _max);
        }
    }
}
